package com.zy.design.pattern.di.meat;

import lombok.Data;

/**
 * @author zhaoyi
 * @date 2021/4/1 10:49
 *
 *利用建造者模式场景
 *      1 类的构造函数必填属性很多
 *      2 如果类的属性之间有一定的依赖关系校验
 *
 *===============================================
 * 利用建造者模式
 *      当 isRef 为 true 的时候
 *          value 表示 String 类型的refId，
 *          type 不需要设置
 *
 *      当 isRef 为 false 的时候
 *          value、type 都需要设置
 *
 */
@Data
public class ConstructorArgs {
    private boolean hasRef;
    private Class type;
    private Object value;

    //1 私有化构造函数
    private ConstructorArgs() {
    }

    private ConstructorArgs(Builder builder) {
        this.hasRef = builder.hasRef;
        this.type = builder.type;
        this.value = builder.value;
    }

    //2 静态内部类
    //检验参数 抛出异常 创建对象返回
    //内部类的对象赋值返回本身,以便于链式调用
    public static class Builder {
        private boolean hasRef;
        private Class type;
        private Object value;

        public ConstructorArgs build() {
            if (!hasRef && (type == null || value == null)) {
                throw new IllegalArgumentException("基本类型不可控");
            }
            if (hasRef && !(value instanceof String)){
                throw new IllegalArgumentException("引用类型id必须是字符串");
            }
            return new ConstructorArgs(this);
        }

        public Builder setHasRef(boolean hasRef) {
            this.hasRef = hasRef;
            //返回自己
            return this;
        }

        public Builder setType(Class type) {
            this.type = type;
            return this;
        }

        public Builder setValue(Object value) {
            this.value = value;
            return this;
        }
    }

}
